package com.hxzy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hxzy.controller.login.req.AdminLoginReq;
import com.hxzy.controller.login.resp.AdminLoginResp;
import com.hxzy.entity.SysRole;
import com.hxzy.entity.SysUser;
import com.hxzy.service.SysMenuService;
import com.hxzy.service.SysRoleService;
import com.hxzy.service.SysUserService;
import com.hxzy.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

/**
* @author admin
* @description 针对表【sys_user(用户信息表)】的数据库操作Service实现
* @createDate 2024-04-07 10:54:29
*/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
    implements SysUserService{

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysMenuService sysMenuService;

    /**
     * 登录方法
     * @param req
     * @return
     */
    @Override
    public AdminLoginResp login(AdminLoginReq req) {
        Authentication authenticate=null;
        try {
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(req.getUsername(), req.getPassword());
            //调用spring security的登录流程操作,自动调用 SysUserServiceImpl中的 loadUserByUsername
             authenticate = this.authenticationManager.authenticate(token);
        }catch (Exception e){
            throw new RuntimeException( e.getMessage());
        }

        //判断是否认证成功了
        if(!authenticate.isAuthenticated()){
             throw new RuntimeException("用户登录认证失败");
        }

        return (AdminLoginResp) authenticate.getPrincipal();
    }

    /**
     * spring security自动调到这里，连接数据库，查询用户名和密码，权限等操作
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        LambdaQueryWrapper<SysUser> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserName, username);

        Optional<SysUser> oneOpt = this.getOneOpt(queryWrapper);
        if(oneOpt.isEmpty()){
            throw new UsernameNotFoundException("用户名不存在");
        }

        SysUser sysUser = oneOpt.get();
        if("2".equals(sysUser.getDelFlag())){
            throw new DisabledException("账户已被注销");
        }

        if("1".equals(sysUser.getStatus())){
           throw new LockedException("账户被锁定");
        }

        //权限
        Set<String>  permissSet=new HashSet<>();


        //查询用户的角色以及它对应的权限
        Set<String> roleSet= this.sysRoleService.getRoleByUserId(sysUser.getUserId());
        if(roleSet.contains("admin")){
            //我们自己定义的，springsecurity不清楚的
            permissSet.add("*:*:*");
        }else{
            //根据角色查询它拥有的菜单
            permissSet= this.sysMenuService.getPermsByRoleSet(roleSet);
        }

        //自定义的对象
        AdminLoginResp  adminLoginResp=new AdminLoginResp();
        adminLoginResp.setUser(sysUser);
        adminLoginResp.setUserId(sysUser.getUserId());
        adminLoginResp.setPermissions(permissSet);

        return adminLoginResp;
    }
}




